Skip to content

fix(hotkey): make Change replace and Remove unbind#707

Open
dschnurbusch wants to merge 1 commit into
altic-dev:mainfrom
dschnurbusch:fix/primary-hotkey-reassignment
Open

fix(hotkey): make Change replace and Remove unbind#707
dschnurbusch wants to merge 1 commit into
altic-dev:mainfrom
dschnurbusch:fix/primary-hotkey-reassignment

Conversation

@dschnurbusch

@dschnurbusch dschnurbusch commented Jul 24, 2026

Copy link
Copy Markdown

Description

Changing or removing a Primary Dictation shortcut currently mutates SwiftUI state and relies on an onChange side effect to persist the list and refresh GlobalHotkeyManager. The shortcut-capture callback can bypass that refresh, leaving the manager's in-memory list stale: Change behaves like Add, and removed shortcuts continue firing until restart.

This PR routes Change and Remove through one persist-and-live-update method. It also permits removing the final primary shortcut, preserving an explicit unbound state instead of silently restoring the legacy shortcut. Fresh installs still receive the existing default when no primary-shortcut preference has ever been stored.

Type of Change

  • 🐞 Bug fix
  • ✨ New feature
  • 💥 Breaking change
  • 🧹 Chore
  • 📝 Documentation update

Related Issue or Discussion

Related to #470 and #498.

#474 contains the direct live-manager refresh for Change, but does not address Remove or an explicitly unbound primary shortcut. #503 covers a narrower active modifier-only press-state edge case; this PR addresses settings-to-live-manager synchronization and removal semantics observed on 1.6.5.

Testing

  • Tested on Intel Mac
  • Tested on Apple Silicon Mac
  • Tested on macOS version:
  • Ran linter locally: swiftlint --strict --config .swiftlint.yml Sources
  • Ran formatter locally: swiftformat --config .swiftformat Sources
  • Ran tests locally:
  • Parsed all changed Swift files with xcrun swiftc -parse
  • Ran git diff --check
  • Fork CI passed SwiftLint, Xcode build, and tests: https://github.com/dschnurbusch/FluidVoice/actions/runs/30101354571

The local machine has Command Line Tools rather than full Xcode, so the full Xcode build/test suite was run on the same commit (83568b8) through the fork's macOS workflow.

Screenshots / Video

Before: FluidVoice 1.6.5 shows Remove disabled when only one Primary Dictation shortcut remains. The submitted change enables removal of that final shortcut; once removed, the row disappears and Add shortcut remains available.

FluidVoice 1.6.5 Global Hotkey settings with disabled Remove button

  • No UI/visual changes; screenshots/video are not applicable.

Notes

The settings mutation now updates persisted state, normalized SwiftUI state, and the live hotkey manager in one call. The existing onChange remains as an idempotent fallback for other state writes.

The explicit empty list is distinguishable from a fresh install: missing preference data still falls back to the legacy/default shortcut, while stored [] remains unbound. The legacy single-shortcut value is left intact for backward-compatible backup/export consumers but is no longer allowed to resurrect an explicitly cleared primary list.

@github-actions github-actions Bot added needs PR template Pull request is missing required template content. needs screenshots Pull request needs screenshot or video evidence. labels Jul 24, 2026
@github-actions

Copy link
Copy Markdown

The PR Policy check is blocking this PR because required template information is missing.

Please update the PR description with:

  • Description
  • Type of Change
  • Related Issue or Discussion
  • Testing
  • Screenshots / Video

Visual files detected:

  • Sources/Fluid/ContentView.swift
  • Sources/Fluid/Persistence/SettingsStore.swift
  • Sources/Fluid/UI/SettingsView.swift

Screenshots or video are required for UI, UX, settings, onboarding, overlay, menu bar, or visual behavior changes. If this PR has no visual changes, check the no-visual-change box in the template.

If this remains incomplete for 48 hours after opening, the PR may be closed.

@greptile-apps

greptile-apps Bot commented Jul 24, 2026

Copy link
Copy Markdown

Greptile Summary

This PR makes primary dictation shortcut changes immediately update persistence and the live hotkey manager.

  • Routes shortcut replacement and Settings binding writes through one update method.
  • Allows removing the final primary shortcut and preserves an explicitly persisted empty list.
  • Keeps the legacy fallback only when no primary-shortcut preference exists.
  • Adds regression coverage for the explicitly unbound state.

Confidence Score: 5/5

The PR appears safe to merge with no actionable defects identified in the changed shortcut update and persistence paths.

Shortcut changes are normalized before updating both SwiftUI state and the live manager, while empty arrays are safely handled by persistence, backup restoration, UI consumers, and hotkey matching.

Reviews (1): Last reviewed commit: "fix(hotkey): make shortcut changes repla..." | Re-trigger Greptile

@github-actions github-actions Bot removed needs PR template Pull request is missing required template content. needs screenshots Pull request needs screenshot or video evidence. labels Jul 24, 2026
@dschnurbusch

Copy link
Copy Markdown
Author

Full fork CI passed on the same head commit (83568b8): SwiftLint, Xcode build, and tests all green. Run: https://github.com/dschnurbusch/FluidVoice/actions/runs/30101354571

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant